//
// Created by F1997 on 2024/12/24.
//

#include "PcapUtils.h"




namespace ntp {

    // 行情1先到包的计数器
    std::atomic<int> Line1Count(0);
    // 行情2先到包的计数器
    std::atomic<int> Line2Count(0);

    // 时间差
    std::atomic<long long> tmDff(0.000000000);
    void PcapUtils::readPcapFile() {
        std::cout << "read pcap file" << std::endl;

        char errbuff[PCAP_ERRBUF_SIZE];
        const char *filename = "/tmp/tmp.FdUHWCPhyb/data/out500_ens3f0__00030_20241017124001.pcap"; // 替换为你的pcap文件名

        // 打开pcap文件
        pcap_t *pcap = pcap_open_offline(filename, errbuff);
        if (pcap == nullptr) {
            //std::cerr << "无法打开文件: " << errbuff << std::endl;
            SPDLOG_LOGGER_INFO(my_logger, "无法打开文件: {}", errbuff);
        }

        // 读取和打印 pcap文件中的每个数据包
        const u_char *packet;
        struct pcap_pkthdr header; // pcap 包头部
        int i= 0;
        while ((packet = pcap_next(pcap, &header)) != nullptr) {
            //std::cout << "得到数据包，长度: " << header.len << " caplen/数据包物理长度: " << header.caplen << " 时间: " << header.ts.tv_sec << "." << header.ts.tv_usec << std::endl;
            // 打印更多的数据包信息
/*        for (int i = 0; i < header.caplen; i++) {
            printf("%02x ", packet[i]); // 以十六进制显示原始载荷数据
        }*/

            //compareTraffic.writeTraffic1(header);
            //CompareTraffic::writeTraffic1(header);
            i++;

            //packet = pcap_next(pcap, &header);
        }

        // 关闭 pcap 句柄
        pcap_close(pcap);
        std::cout << "包总数" << i << std::endl;

        //return 0;

    }


// 检查是否到达计数起点
    bool PcapUtils::checkIsStart(std::chrono::system_clock::time_point startTime, int offset) {
        // 当前时间是否 >= 启动时间 + 偏移时间
        // 获取当前时间作为启动时间
        //return (std::chrono::system_clock::now() >= startTime + std::chrono::seconds(offset)) ? true : false;
        return (std::chrono::system_clock::now() >= startTime + std::chrono::seconds(offset)); // 简化后
    }


// 从网络接口读取数据包并解析 = 会报错，对‘pcap_open’未定义的引用
/*int PcapUtils::readNetworkInterface() {
    pcap_if_t *alldevs;
    pcap_t *handle;
    char errbuf[PCAP_ERRBUF_SIZE];
    const unsigned char *packet; // 指向的是包的原始数据载荷
    struct pcap_pkthdr header; // 包头中包含了时间戳、捕获长度和原始数据长度等信息
    int res;

     // 获取网络接口
    if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1) {
        fprintf(stderr, "Error in pcap_findalldevs: %s\n", errbuf);
        return 1;
    }

     // 打开网络接口
    handle = pcap_open(alldevs->name, 65536, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, errbuf);
    if (handle == NULL) {
        fprintf(stderr, "Couldn't open device %s: %s\n", alldevs->name, errbuf);
        pcap_freealldevs(alldevs);
        return 2;
    }

    pcap_freealldevs(alldevs);

     // 读取并解析网络包
    // pcap_next_ex()函数会阻塞等待，直到捕获到一个网络包或超时
    //if (pcap_loop(handle, 10, packet_handler, reinterpret_cast<u_char*>(&compareTraffic)) < 0)  // pcap_loop()函数会阻塞等待，直到捕获到一个网络包或超时
    while ((res = pcap_next_ex(handle, reinterpret_cast<pcap_pkthdr **>(&header), &packet)) >= 0) {
        if (res == 0)
             // 超时
            continue;

         // 包头信息
        printf("Timestamp: %lld.%lld\n", header.ts.tv_sec, header.ts.tv_usec);
        printf("Caplen: %d\n", header.caplen);
        printf("Len: %d\n", header.len);

         // 有效载荷
        printf("Packet: ");
        for (int i = 0; i < header.caplen; i++) {
            printf("%02x ", packet[i]);
        }
        printf("\n");
    }

    if (res == -1) {
        fprintf(stderr, "Error reading the packets: %s\n", pcap_geterr(handle));
        return 3;
    }

    pcap_close(handle);
    return 0;

}*/



// 参考 = 获取pcap报文的ns级时间戳
// https://blog.csdn.net/xuan196/article/details/135538876
// 从网卡获取
    int PcapUtils::readNetworkIfaceLine(std::string sectionId, std::chrono::system_clock::time_point startTime, IniReader* iniCfg, SafeQueue<MarketData>* data_queue) {

        //std::cout << "访问全局变量:" << global_message << std::endl;
        //std::cout << "初始队列大小:" << data_queue.size() << std::endl;

        // 从配置文件中获取配置
        std::string device = iniCfg->ReadString(sectionId.data(), "device","");
        std::string sourceIP = iniCfg->ReadString(sectionId.data(), "sourceIP","");
        std::string destinationIP = iniCfg->ReadString(sectionId.data(), "destinationIP","");
        std::string destinationPort = iniCfg->ReadString(sectionId.data(), "destinationPort","");
        std::string filterStr = iniCfg->ReadString(sectionId.data(), "filterStr",""); // 抓包过滤条件

        std::string target_time_all = iniCfg->ReadString("MODE", "target_time_all","");

        char errbuf[PCAP_ERRBUF_SIZE];
        pcap_t *handle;

        // 网络接口名称
        const char *dev = device.c_str(); //"ens33";

        // 创建 pcap 句柄
        handle = pcap_create(dev, errbuf);
        if (handle == NULL) {
            fprintf(stderr, "无法创建 pcap 句柄: %s\n", errbuf);
            SPDLOG_LOGGER_ERROR(my_logger, "无法创建 pcap 句柄: %s\n", errbuf);
            return 1;
        }

        // 设置纳秒级时间戳精度
        // 无，PCAP_TSTAMP_PRECISION_NANO(不一定都是9位) ，PCAP_TSTAMP_PRECISION_MICRO
        // t1=1739242273 t2=235530，t1=1739242599 t2=998971747，t1=1739242518 t2=683691
        if (pcap_set_tstamp_precision(handle, PCAP_TSTAMP_PRECISION_NANO) != 0) {// PCAP_TSTAMP_PRECISION_MICRO, PCAP_TSTAMP_PRECISION_NANO
            fprintf(stderr, "设置纳秒级时间戳精度失败: %s\n", pcap_geterr(handle));
            SPDLOG_LOGGER_ERROR(my_logger, "设置纳秒级时间戳精度失败: %s\n", pcap_geterr(handle));
            // 也可以选择在这里退出，如果纳秒级别时间戳是必需的
        }

        // 设置捕获参数
        if (pcap_set_snaplen(handle, 65535) != 0) { // 设置最大捕获长度
            std::cerr << "Error setting snaplen: " << pcap_geterr(handle) << std::endl;
            return -1;
        }

        if (pcap_set_promisc(handle, 1) != 0) { // 设置混杂模式
            std::cerr << "Error setting promiscuous mode: " << pcap_geterr(handle) << std::endl;
            // goto cleanup; 跳转到错误处理逻辑
            return -1;
        }

        //if (pcap_set_timeout(handle, 1000) != 0) { // 设置超时时间（毫秒） = 是否有必要，报错？？？
        //    std::cerr << "Error setting timeout: " << pcap_geterr(handle) << std::endl;
        //    //goto cleanup;
        //    return -1;
        //}

        // 设置即使模式，为了使收到的报文尽快给我们的处理程序，需要设置成immediate模式
        if (pcap_set_immediate_mode(handle, 1) != 0){ // 0:禁用立即模式，1:立即模式，一个是批量，一个是立即收？？？
            std::cerr << "Error setting timeout: " << pcap_geterr(handle) << std::endl;
            return -1;
        }

        // 激活 pcap 句柄
        if (pcap_activate(handle) != 0) {
            fprintf(stderr, "激活 pcap 句柄失败: %s\n", pcap_geterr(handle));
            SPDLOG_LOGGER_ERROR(my_logger, "激活 pcap 句柄失败: %s\n", pcap_geterr(handle));
            pcap_close(handle);
            return 1;
        }

        // 设置过滤器
        struct bpf_program fp;
        char filter_exp2[] = "host 192.168.192.1"; // 过滤IP数据包，等价的写法，c_str 后为 const char *
        const char *filter_exp = filterStr.c_str() ;
        if (pcap_compile(handle, &fp, filter_exp, 0, PCAP_NETMASK_UNKNOWN) < 0) {
            fprintf(stderr, "无法解析过滤器 %s: %s\n", filter_exp, pcap_geterr(handle));
            SPDLOG_LOGGER_ERROR(my_logger, "无法解析过滤器 %s: %s\n", filter_exp, pcap_geterr(handle));
            exit(EXIT_FAILURE);
        }
        if (pcap_setfilter(handle, &fp) < 0) {
            fprintf(stderr, "无法应用过滤器 %s: %s\n", filter_exp, pcap_geterr(handle));
            SPDLOG_LOGGER_ERROR(my_logger, "无法应用过滤器 %s: %s\n", filter_exp, pcap_geterr(handle));
            exit(EXIT_FAILURE);
        }

        // 检查实际的时间戳精度
        int tstamp_precision = pcap_get_tstamp_precision(handle);

        struct pcap_pkthdr *header;
        const u_char *packet;
        int res;

        try {
            auto currentTime = std::chrono::system_clock::now();
            // 当前时间小于指定时间，则忙等
            while ( currentTime.time_since_epoch().count() <= parse_date_to_timestamp(target_time_all)*1000000000 ) {
                // 当前时间小于目标时间，等待100毫秒后再次检查
                //std::this_thread::sleep_for(std::chrono::milliseconds(1));
                std::this_thread::sleep_for(std::chrono::nanoseconds(10)); // 10ns
                currentTime = std::chrono::system_clock::now();
                //std::cout << "1 忙等中。。。" << std::endl;
            }

            std::cout << "pcap开始抓取数据包 tm:" << currentTime.time_since_epoch().count() << " > " << parse_date_to_timestamp(target_time_all)*1000000000 << std::endl;
            SPDLOG_LOGGER_INFO(my_logger,"{} 开始抓取数据",sectionId.data());
            int pkgCount = 0;
            // 捕获循环
            while ((res = pcap_next_ex(handle, &header, &packet)) >= 0 ) { // header=报文头，packet=报文内容，数据包
                if (res == 0) {
                    // 超时未收到数据包，告警
                    std::cout << "超时未收到数据包，告警" << std::endl;
                    continue;
                }
                if(res == -1) {
                    printf("读取数据包时出错: %s\n", pcap_geterr(handle));
                    return -1;
                }

                // 解析数据包并获取有效数据
                //std::cout << "得到数据包，长度: " << header->len << " caplen/数据包物理长度: " << header->caplen << " 时间: " << header->ts.tv_sec << "." << header->ts.tv_usec << std::endl;
                //compareTraffic.writeTraffic1(*header);
                //parse_packet(header,packet);


                // 判断队列是否可用，队列未满 = 底层是动态扩容的，没有"满"的时候，除非资源耗尽
                {
                    pkgCount++; // 当前接受的总包数，包数不是连续的？？？

                    MarketData marketData;
                    memset(&marketData, 0x00, sizeof(MarketData));
                    marketData.lineFlag = sectionId;
                    // 包外数据
                    marketData.len = header->len; //抓到数据包，长度
                    marketData.caplen = header->caplen; // header->caplen 数据包物理长度
                    marketData.time1 = header->ts.tv_sec; // 抓包的秒级时间戳
                    marketData.time2 = header->ts.tv_usec; // 纳秒级别时间戳
                    marketData.local_time = std::chrono::high_resolution_clock::now(); // 本地时间戳，纳秒级别
                    marketData.pkgCount = pkgCount; // 包计数器，编号从1开始

                    // 解析数据包中的数据
                    marketData.pkthdr = header; // 原始包头数据
                    marketData.packet = packet; // 原始payload数据
                    parse_packet_shfe(header, packet, marketData);
                    //parse_packet_dce(header, packet, marketData);

                   data_queue->enqueue(marketData); // 在 queue 的尾部添加一个元素的副本
                }
            }

        } catch (const std::invalid_argument& e) {
            std::cerr << "Caught an invalid argument: " << e.what() << std::endl;
            // 处理异常，例如提供错误信息、重试操作或者返回错误码
            return -1;
        }

        pcap_close(handle);
        return 0;
    }

    // 从网卡获取，解析后直接写入文件
    int PcapUtils::readNetwork(std::string sectionId, std::chrono::system_clock::time_point startTime, IniReader* iniCfg) {

        // 从配置文件中获取配置
        std::string device = iniCfg->ReadString(sectionId.data(), "device","");
        std::string sourceIP = iniCfg->ReadString(sectionId.data(), "sourceIP","");
        std::string destinationIP = iniCfg->ReadString(sectionId.data(), "destinationIP","");
        std::string destinationPort = iniCfg->ReadString(sectionId.data(), "destinationPort","");
        std::string filterStr = iniCfg->ReadString(sectionId.data(), "filterStr",""); // 抓包过滤条件

        std::string target_time_all = iniCfg->ReadString("MODE", "target_time_all","");

        char errbuf[PCAP_ERRBUF_SIZE];
        pcap_t *handle;

        // 网络接口名称
        const char *dev = device.c_str(); //"ens33";

        // 创建 pcap 句柄
        handle = pcap_create(dev, errbuf);
        if (handle == NULL) {
            fprintf(stderr, "无法创建 pcap 句柄: %s\n", errbuf);
            SPDLOG_LOGGER_ERROR(my_logger, "无法创建 pcap 句柄: %s\n", errbuf);
            return 1;
        }

        // 设置纳秒级时间戳精度
        // 无，PCAP_TSTAMP_PRECISION_NANO(不一定都是9位) ，PCAP_TSTAMP_PRECISION_MICRO
        // t1=1739242273 t2=235530，t1=1739242599 t2=998971747，t1=1739242518 t2=683691
        if (pcap_set_tstamp_precision(handle, PCAP_TSTAMP_PRECISION_NANO) != 0) {// PCAP_TSTAMP_PRECISION_MICRO, PCAP_TSTAMP_PRECISION_NANO
            fprintf(stderr, "设置纳秒级时间戳精度失败: %s\n", pcap_geterr(handle));
            SPDLOG_LOGGER_ERROR(my_logger, "设置纳秒级时间戳精度失败: %s\n", pcap_geterr(handle));
            // 也可以选择在这里退出，如果纳秒级别时间戳是必需的
        }

        // 设置捕获参数
        if (pcap_set_snaplen(handle, 65535) != 0) { // 设置最大捕获长度
            std::cerr << "Error setting snaplen: " << pcap_geterr(handle) << std::endl;
            return -1;
        }

        if (pcap_set_promisc(handle, 1) != 0) { // 设置混杂模式
            std::cerr << "Error setting promiscuous mode: " << pcap_geterr(handle) << std::endl;
            // goto cleanup; 跳转到错误处理逻辑
            return -1;
        }

        //if (pcap_set_timeout(handle, 1000) != 0) { // 设置超时时间（毫秒） = 是否有必要，报错？？？
        //    std::cerr << "Error setting timeout: " << pcap_geterr(handle) << std::endl;
        //    //goto cleanup;
        //    return -1;
        //}

        // 设置即使模式，为了使收到的报文尽快给我们的处理程序，需要设置成immediate模式
        if (pcap_set_immediate_mode(handle, 1) != 0){ // 0:禁用立即模式，1:立即模式，一个是批量，一个是立即收？？？
            std::cerr << "Error setting timeout: " << pcap_geterr(handle) << std::endl;
            return -1;
        }

        // 激活 pcap 句柄
        if (pcap_activate(handle) != 0) {
            fprintf(stderr, "激活 pcap 句柄失败: %s\n", pcap_geterr(handle));
            SPDLOG_LOGGER_ERROR(my_logger, "激活 pcap 句柄失败: %s\n", pcap_geterr(handle));
            pcap_close(handle);
            return 1;
        }

        // 设置过滤器
        struct bpf_program fp;
        char filter_exp2[] = "host 192.168.192.1"; // 过滤IP数据包，等价的写法，c_str 后为 const char *
        const char *filter_exp = filterStr.c_str() ;
        if (pcap_compile(handle, &fp, filter_exp, 0, PCAP_NETMASK_UNKNOWN) < 0) {
            fprintf(stderr, "无法解析过滤器 %s: %s\n", filter_exp, pcap_geterr(handle));
            SPDLOG_LOGGER_ERROR(my_logger, "无法解析过滤器 %s: %s\n", filter_exp, pcap_geterr(handle));
            exit(EXIT_FAILURE);
        }
        if (pcap_setfilter(handle, &fp) < 0) {
            fprintf(stderr, "无法应用过滤器 %s: %s\n", filter_exp, pcap_geterr(handle));
            SPDLOG_LOGGER_ERROR(my_logger, "无法应用过滤器 %s: %s\n", filter_exp, pcap_geterr(handle));
            exit(EXIT_FAILURE);
        }

        // 检查实际的时间戳精度
        int tstamp_precision = pcap_get_tstamp_precision(handle);

        struct pcap_pkthdr *header;
        const u_char *packet;
        int res;

        try {
            auto currentTime = std::chrono::system_clock::now();
            // 当前时间小于指定时间，则忙等
            while ( currentTime.time_since_epoch().count() <= parse_date_to_timestamp(target_time_all)*1000000000 ) {
                // 当前时间小于目标时间，等待100毫秒后再次检查
                //std::this_thread::sleep_for(std::chrono::milliseconds(1));
                std::this_thread::sleep_for(std::chrono::nanoseconds(10)); // 10ns
                currentTime = std::chrono::system_clock::now();
                //std::cout << "1 忙等中。。。" << std::endl;
            }

            std::cout << "pcap开始抓取数据包 tm:" << currentTime.time_since_epoch().count() << " > " << parse_date_to_timestamp(target_time_all)*1000000000 << std::endl;
            SPDLOG_LOGGER_INFO(my_logger,"{} 开始抓取数据",sectionId.data());
            int pkgCount = 0;
            // 捕获循环
            while ((res = pcap_next_ex(handle, &header, &packet)) >= 0 ) { // header=报文头，packet=报文内容，数据包
                if (res == 0) {
                    // 超时未收到数据包，告警
                    std::cout << "超时未收到数据包，告警" << std::endl;
                    continue;
                }
                if(res == -1) {
                    printf("读取数据包时出错: %s\n", pcap_geterr(handle));
                    return -1;
                }

                // 解析数据包并获取有效数据
                //std::cout << "得到数据包，长度: " << header->len << " caplen/数据包物理长度: " << header->caplen << " 时间: " << header->ts.tv_sec << "." << header->ts.tv_usec << std::endl;
                //compareTraffic.writeTraffic1(*header);
                //parse_packet(header,packet);


                // 判断队列是否可用，队列未满 = 底层是动态扩容的，没有"满"的时候，除非资源耗尽
                {
                    pkgCount++; // 当前接受的总包数，包数不是连续的？？？

                    MarketData marketData;
                    memset(&marketData, 0x00, sizeof(MarketData));
                    marketData.lineFlag = sectionId;
                    // 包外数据
                    marketData.len = header->len; //抓到数据包，长度
                    marketData.caplen = header->caplen; // header->caplen 数据包物理长度
                    marketData.time1 = header->ts.tv_sec; // 抓包的秒级时间戳
                    marketData.time2 = header->ts.tv_usec; // 纳秒级别时间戳
                    marketData.local_time = std::chrono::high_resolution_clock::now(); // 本地时间戳，纳秒级别
                    marketData.pkgCount = pkgCount; // 包计数器，编号从1开始

                    // 解析数据包中的数据
                    marketData.pkthdr = header; // 原始包头数据
                    marketData.packet = packet; // 原始payload数据
                    parse_packet_shfe(header, packet, marketData);
                    //parse_packet_dce(header, packet, marketData);

                    data_queue->enqueue(marketData); // 在 queue 的尾部添加一个元素的副本
                }
            }

        } catch (const std::invalid_argument& e) {
            std::cerr << "Caught an invalid argument: " << e.what() << std::endl;
            // 处理异常，例如提供错误信息、重试操作或者返回错误码
            return -1;
        }

        pcap_close(handle);
        return 0;
    }


    // 读队列
    int PcapUtils::readMsg(std::shared_ptr<spdlog::logger> _my_logger, IniReader* iniCfg,
                           SafeQueue<MarketData>* data_queue1, SafeQueue<MarketData>* data_queue2) {
        SPDLOG_LOGGER_INFO(my_logger, "readMsg");

        //std::cout << "队列大小1" << shareDataClzz->data_queue1.size() << std::endl;
        //std::cout << "消费者：data_queue-队列1大小：" << data_queue1->getSize() << std::endl;
        //sleep(3);
        std::string fileName = "delayFile.txt";

        std::ofstream file(fileName);
        // 检查文件是否成功打开
        if (!file.is_open()) {
            SPDLOG_LOGGER_ERROR(my_logger, "文件打开失败: {}",fileName);
            std::cerr << "文件打开失败: " << fileName << std::endl;
            return -1;
        }
        //file << "统计次数,包总数,a比b快的百分比,a减b的时间差" << std::endl;

        int lineCount1 = 0;
        int lineCount2 = 0;
        int m1_packet_no = 0;
        int m2_packet_no = 0;
        while (true ) {
            // 等待采样间隔
            //std::this_thread::sleep_for(std::chrono::milliseconds(3000));

            // 队列不空，则消费数据
            auto a = data_queue1->getSize();
            auto b = data_queue2->getSize();

            if (1/*a >= 0 && b >= 0*/) {
                MarketData md1 = data_queue1->tryQequeue();
                MarketData md2 = data_queue2->tryQequeue();

                //file << "消费者:" << data_queue1->getSize() << "|" << data_queue2->getSize() << "<>" << a << "|" << b << std::endl;
                //std::cout << "消费者:" << data_queue1->getSize() << "|" << data_queue2->getSize() << "<>" << a << "|" << b
                //<< " data "<< md1.len << "|" << md2.len
                //<< ":" << md1.caplen << "|" << md2.caplen
                //<< " t1=" << md1.time1 << "|" << md2.time1
                //<< " t2=" << md1.time2 << "|" << md2.time2
                //<< " pkgCount=" << md1.pkgCount << "|" << md2.pkgCount
                //<< std::endl;
                //std::cout
                //<< "    local_time(ns)=" << md1.local_time.time_since_epoch().count() << "|" << md2.local_time.time_since_epoch().count()
                //<< " packet_no=" << md1.packet_no << "|" << md2.packet_no
                //<< " time=" << md1.snap_time << "|" << md2.snap_time
                //<< " millisec=" << md1.snap_millisec << "|" << md2.snap_millisec
                //<< std::endl;

                // 解析数据包中的数据
                //parse_packet(data_queue->dequeue().pkthdr, data_queue->dequeue().packet);

                // 相同包序号下，抓包时间的差值
                // seqNo连续且相同(不为0)时就用其判断
                int delay = NULL;
                //std::cout << "==" << (md1.snap_time != 0) << " lineCount2=" << lineCount2 << std::endl;
                if (md1.snap_time != 0 || md2.snap_time != 0) { // 解包的交易所时间不为0，则表示是行情数据包
                    //if ( md1.pkgCount == md2.pkgCount ) {
                        //if (md1.packet_no != 0 ) { // 包序号不为0
/*                            if (md1.time2 >= md2.time2) { // 1比2块
                                delay = md1.time2 - md2.time2;
                                lineCount1++;
                                std::cout << " delay=" << delay << std::endl;
                            } else { // 2比1块
                                delay = md1.time2 - md2.time2;
                                lineCount2++;
                                std::cout << " delay=" << delay << std::endl;
                            }*/

                            // pkgNo大的，则接收到的数据包多，行情快
                            //
                    if (md1.packet_no != 0) m1_packet_no = md1.packet_no;
                    if (md2.packet_no != 0) m2_packet_no = md2.packet_no;
                            if (m1_packet_no > m2_packet_no) {
                                // 1快
                                lineCount1++;
                                Line1Count.fetch_add(1);
                                delay = (md1.time1*100000000 + md1.time2) - (md2.time1*100000000 + md2.time2); // 快的纳秒数
                            } else {
                                // 2快
                                lineCount2++;
                                Line2Count.fetch_add(1);
                                delay = (md1.time1*100000000 + md1.time2) - (md2.time1*100000000 + md2.time2);
                            }
                        //}
/*                        // 行情包编号不同，则用协议头的秒级时间
                        if (md1.time1 == md2.time1) { // 包头秒级时间
                            if (md1.time2 >= md2.time2) { // 1比2块
                                delay = md1.time2 - md2.time2;
                                lineCount1++;
                                std::cout << " delay=" << delay << std::endl;
                            } else { // 2比1块
                                delay = md1.time2 - md2.time2;
                                lineCount2++;
                                std::cout << " delay=" << delay << std::endl;
                            }
                        }*/
                    //}


                    // 写入文件
                    file << a << "|" << b << "," // 队列大小
                    << md1.pkgCount << "|" << md2.pkgCount << "," // 收到的总包数
                    << md1.packet_no << "|" << md2.packet_no << "," // 行情编号
                    << md1.snap_time << "|" << md2.snap_time << "," // 行情时间戳
                    << md1.time1 << "|" << md2.time1 << "," // 抓包时间戳-秒
                    << md1.time2 << "|" << md2.time2 << "," // 抓包时间戳-纳秒级别
                    << (md1.time1 - md2.time1) << ","  // 时间差值-秒
                    << (md1.time2 - md2.time2) << "," // 时间差值-纳秒级别

                    << lineCount1 << "|" << lineCount2 // a先到达的包数,b先到达的包数
                    //<< delay
                    << std::endl;

                } else {
                    //std::cout << "无效的报文" << std::endl;
                }
            } else {
                std::cout << "队列为空" << std::endl;
                //SPDLOG_LOGGER_INFO(my_logger, "队列为空");
            }

        }


        return 0;
    }

// 采样统计
    int PcapUtils::sampled(std::shared_ptr<spdlog::logger> _my_logger, IniReader* iniCfg) {
        //std::cout << "readMsg" << std::endl;
        my_logger->info("采样统计");
        while(1) {}
        //compareTraffic.sampledAndSave(my_logger);
        return 0;
    }



// 解析时间字符串并转换为 time_point =
// tm ---> time_t ---> time_point
/*std::chrono::system_clock::time_point PcapUtils::parseTime(const std::string& timeStr) {
    std::tm tm = {};
    std::istringstream ss(timeStr);

    // 使用 std::get_time 解析时间字符串
    ss << std::get_time(&tm, "%Y-%m-%d %H:%M:%S");

    if (ss.fail()) {
        throw std::runtime_error("Failed to parse time string");
    }

    // 将 struct tm 转换为 time_t
    std::time_t time_t_value = mktime(&tm);

    // 将 time_t 转换为 system_clock::time_point
    auto duration = std::chrono::system_clock::from_time_t(time_t_value);

    // 处理纳秒部分
    std::string nanosecondsStr = timeStr.substr(20);
    std::istringstream nsStream(nanosecondsStr);
    long long nanoseconds;
    nsStream >> nanoseconds;

    // 将纳秒部分添加到 duration
    duration += std::chrono::nanoseconds(nanoseconds);

    return duration;
}*/


// 将时间字符串转换为 time_point
    std::chrono::system_clock::time_point PcapUtils::string_to_time_point(const std::string& str) {
        // 解析字符串
        int year, month, day, hour, minute, second;
        std::istringstream ss(str);
        char delimiter;

        ss >> year >> delimiter >> month >> delimiter >> day >> delimiter
           >> hour >> delimiter >> minute >> delimiter >> second;

        // 创建 tm 结构体
        std::tm tm_struct = {};
        tm_struct.tm_year = year - 1900; // 年份从 1900 开始计算
        tm_struct.tm_mon = month - 1;     // 月份从 0 开始计算
        tm_struct.tm_mday = day;
        tm_struct.tm_hour = hour;
        tm_struct.tm_min = minute;
        tm_struct.tm_sec = second;

        // 转换为 time_t
        std::time_t time_t_value = mktime(&tm_struct);

        // 转换为 time_point
        return std::chrono::system_clock::from_time_t(time_t_value);
    }

// 时间日期转时间戳
// 解析日期字符串并转换为时间戳
    time_t PcapUtils::parse_date_to_timestamp(const std::string& date_str) {
        struct tm time_struct = {};
        const char* format = "%Y-%m-%d %H:%M:%S";

        // 解析日期字符串
        if (strptime(date_str.c_str(), format, &time_struct) == nullptr) {
            std::cerr << "Invalid date format:" << date_str.c_str() << ", " << format << std::endl;
            throw std::invalid_argument("日期格式无效");
        }

        // 将 tm 结构体转换为时间戳
        time_t timestamp = mktime(&time_struct);
        if (timestamp == -1) {
            throw std::runtime_error("Failed to convert to timestamp");
        }

        return timestamp;
    }


    // 解析数据包-dce
    void PcapUtils::parse_packet_dce(const struct pcap_pkthdr* pkthdr, const u_char* packet, MarketData& marketData) {
        std::cout << "解析数据包" << std::endl;
        // 输出原始数据包内容，以十六进制形式输出
        for (int i = 0; i < pkthdr->caplen; i++) {
            printf("%02x ", packet[i]);
            if ((i + 1) % 16 == 0) {
                printf("\n");
            }
        }
        printf("\n=================================\n");

        // 解析以太网头部
        struct my_ether_header *eth_hdr = (struct my_ether_header *)packet;
        if (ntohs(eth_hdr->ether_type) == /*0*/0x0800) {
            // 解析IP头部
            struct my_ip_header *ip_hdr = (struct my_ip_header *)(packet + sizeof(struct my_ether_header));
            //printf("ip_v: %d\n", ip_hdr->ip_v);
            //printf("ip_src: %s\n", inet_ntoa(ip_hdr->ip_src));
            //printf("ip_dst: %s\n", inet_ntoa(ip_hdr->ip_dst));
            if (ip_hdr->ip_p == IPPROTO_TCP) {
                // 解析TCP头部
                struct my_tcp_header *tcp_hdr = (struct my_tcp_header *)(packet + sizeof(struct my_ether_header) + (ip_hdr->ip_hl * 4));

                // 计算payload的起始位置
                int payload_offset = sizeof(struct my_ether_header) + (ip_hdr->ip_hl * 4) + (tcp_hdr->th_off * 4);
                int payload_size = pkthdr->len - payload_offset;

/*                // 打印基本信息
                printf("Source IP: %s\n", inet_ntoa(ip_hdr->ip_src));
                printf("Destination IP: %s\n", inet_ntoa(ip_hdr->ip_dst));
                printf("Source Port: %d\n", ntohs(tcp_hdr->th_sport));
                printf("Destination Port: %d\n", ntohs(tcp_hdr->th_dport));
                printf("Payload Size: %d bytes\n", payload_size);

                // 打印payload
                if (payload_size > 0) {
                    printf("Payload:\n");
                    for (int i = 0; i < payload_size; ++i) {
                        printf("%02x ", packet[payload_offset + i]);
                        if ((i + 1) % 16 == 0) {
                            printf("\n");
                        }
                    }
                    printf("\n");
                }*/

            }
            else if (ip_hdr->ip_p == IPPROTO_UDP) { //
                struct my_udp_header *udp_hdr = (struct my_udp_header *)(packet + sizeof(struct my_ether_header) + (ip_hdr->ip_hl * 4));
                // 计算payload的起始位置
                int payload_offset = sizeof(struct my_ether_header) + (ip_hdr->ip_hl * 4) + sizeof(struct my_udp_header); // udp包头长度固定为8？？？
                int payload_size = pkthdr->len - payload_offset; // 本个报文
                if (payload_size > 25) {
                    // dmdp报文头，每个行情都以合约号域始
                    struct DMDPHeader *dmdpHeader = (struct DMDPHeader *)(packet + payload_offset);

                    // 打印原始payload数据
                    for (int i = 0; i < 32; ++i) {
                        printf("%02x ", packet[payload_offset + i]);
                        if ((i + 1) % 16 == 0) {
                            printf("\n");
                        }
                    }
                    printf("\n------\n");

                    printf("ip_src: %s\n", inet_ntoa(ip_hdr->ip_src)); // ip
                    printf("ip_dst: %s\n", inet_ntoa(ip_hdr->ip_dst));
                    printf("DstPort: %d\n", udp_hdr->DstPort); // 端口
                    printf("SrcPort: %d\n", udp_hdr->SrcPort);
                    printf("pkthdr.len: %d\n", pkthdr->len); // 长度
                    printf("udp_hdr.len: %d\n", udp_hdr->len); // 长度
                    printf("checkSum: %d\n", udp_hdr->checkSum);

                    printf("payload_offset: %d\n", payload_offset);
                    printf("payload_size: %d\n", payload_size);

                    printf("---\n");
                    printf("pkg_size: %d\n", dmdpHeader->pkg_size);
                    std::cout << "pkg_type: " << ntohs(dmdpHeader->pkg_type) << std::endl; // 0x0002
                    //printf("pkg_type: %d\n", dmdpHeader->pkg_type); // l2行情=pkg_type=0x0003
                    printf("version: %d\n", dmdpHeader->version);
                    printf("flag: %d\n", dmdpHeader->flag);
                    printf("mdg_no: %d\n", dmdpHeader->mdg_no);
                    printf("start_seq_no: %d\n", dmdpHeader->start_seq_no);
                    printf("start_seq_no: %llu\n", ntohs(dmdpHeader->start_seq_no));
                    printf("seq_num: %d\n", dmdpHeader->seq_num);
                    printf("send_time: %llu\n", dmdpHeader->send_time);
                    printf("send_time: %llu\n", ntohs(dmdpHeader->send_time));
                    printf("reserved: %d\n", dmdpHeader->reserved);
                    printf("=================================\n");

                    // 包内的数据提取到 MarketData
                    //marketData.snap_time = mirpHeader->snap_time;
                    //marketData.snap_millisec = mirpHeader->snap_millisec;
                    //marketData.packet_no = mirpHeader->packet_no;

                    // 进一步解析域串
                }
            }
        }
    }

    // 解析数据包-shfe
    void PcapUtils::parse_packet_shfe(const struct pcap_pkthdr* pkthdr, const u_char* packet, MarketData& marketData) {
/*        std::cout << "解析数据包" << std::endl;
        // 输出原始数据包内容，以十六进制形式输出
        for (int i = 0; i < 20*//*pkthdr->caplen*//*; i++) {
            printf("%02x ", packet[i]);
            if ((i + 1) % 20 == 0) {
                printf("\n");
            }
        }
        printf("\n");*/

        // 解析以太网头部
        struct my_ether_header *eth_hdr = (struct my_ether_header *)packet;
        if (ntohs(eth_hdr->ether_type) == /*0*/0x0800) {
            // 解析IP头部
            struct my_ip_header *ip_hdr = (struct my_ip_header *)(packet + sizeof(struct my_ether_header));
            //printf("ip_v: %d\n", ip_hdr->ip_v);
            //printf("ip_src: %s\n", inet_ntoa(ip_hdr->ip_src));
            //printf("ip_dst: %s\n", inet_ntoa(ip_hdr->ip_dst));
            if (ip_hdr->ip_p == IPPROTO_TCP) {
                // 解析TCP头部
                struct my_tcp_header *tcp_hdr = (struct my_tcp_header *)(packet + sizeof(struct my_ether_header) + (ip_hdr->ip_hl * 4));

                // 计算payload的起始位置
                int payload_offset = sizeof(struct my_ether_header) + (ip_hdr->ip_hl * 4) + (tcp_hdr->th_off * 4);
                int payload_size = pkthdr->len - payload_offset;

/*                // 打印基本信息
                printf("Source IP: %s\n", inet_ntoa(ip_hdr->ip_src));
                printf("Destination IP: %s\n", inet_ntoa(ip_hdr->ip_dst));
                printf("Source Port: %d\n", ntohs(tcp_hdr->th_sport));
                printf("Destination Port: %d\n", ntohs(tcp_hdr->th_dport));
                printf("Payload Size: %d bytes\n", payload_size);

                // 打印payload
                if (payload_size > 0) {
                    printf("Payload:\n");
                    for (int i = 0; i < payload_size; ++i) {
                        printf("%02x ", packet[payload_offset + i]);
                        if ((i + 1) % 16 == 0) {
                            printf("\n");
                        }
                    }
                    printf("\n");
                }*/

            }
            else if (ip_hdr->ip_p == IPPROTO_UDP) {
                struct my_udp_header *udp_hdr = (struct my_udp_header *)(packet + sizeof(struct my_ether_header) + (ip_hdr->ip_hl * 4));
                // 计算payload的起始位置
                int payload_offset = sizeof(struct my_ether_header) + (ip_hdr->ip_hl * 4) + sizeof(struct my_udp_header); // udp包头长度固定为8？？？
                int payload_size = pkthdr->len - payload_offset;
                if (payload_size > 25) {
                    // mirp报文头
                    struct MIRPHeader *mirpHeader = (struct MIRPHeader *)(packet + payload_offset);

                    //printf("DstPort: %d\n", udp_hdr->DstPort);
                    //printf("SrcPort: %d\n", udp_hdr->SrcPort);
                    //printf("len: %d\n", udp_hdr->len);
                    //printf("checkSum: %d\n", udp_hdr->checkSum);

                    //printf("payload_offset: %d\n", payload_offset);
                    //printf("payload_size: %d\n", payload_size);

                    //printf("mirpHeader->type_id: %d\n", mirpHeader->type_id);
                    //printf("%d\n", mirpHeader->center_change_no);
                    //printf("%d\n", mirpHeader->comm_phase_no); // 交易日
                    //printf("mirpHeader->snap_time: %d\n", mirpHeader->snap_time);
                    //printf("mirpHeader->snap_millisec: %d\n", mirpHeader->snap_millisec);
                    //printf("mirpHeader->packet_no: %d\n", mirpHeader->packet_no); // 唯一编号，有可能重复，表示多个包是同一个行情
                    //printf("=================================\n");

                    // 包内的数据提取到 MarketData
                    marketData.snap_time = mirpHeader->snap_time;
                    marketData.snap_millisec = mirpHeader->snap_millisec;
                    marketData.packet_no = mirpHeader->packet_no;

                    // 进一步解析域串
                }

            }
        }
    }

    // 解析数据包-zce
    void PcapUtils::parse_packet_zce(const struct pcap_pkthdr* pkthdr, const u_char* packet, MarketData& marketData) {
    }

} // ntp